home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
126-150
/
disk_149
/
less
/
src
/
print.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
10KB
|
493 lines
/* print.c
simple print file utility for less by: Bob Leivian
print -nh^ld#99|99t9wp:<string> file1 {-nh...}file2 file3 ...
this is designed to be called from the less with the
expanded list of files to print with a option list
*/
#include <stdio.h>
#include <ctype.h>
long Open();
#define MODE_OLDFILE 1005L
#define MODE_NEWFILE 1006L
long std_out;
extern char prog_name[];
/* this can be set with options */
int numbers = 0;
int headers = 0;
int control = 0;
int prefix = 0;
int lines_per_page = 0;
int chars_per_line = 0;
int tab_stops = 0;
long printer = 0;
start_print(my_argc, my_argv)
int my_argc;
char *my_argv[];
{
int i;
char *p;
char name[30];
char theprefix [30];
char c;
if (printer == 0) {
printer = Open("PRT:", MODE_NEWFILE);
if (!printer) exit(27);
}
while (my_argv[1]) {
/* process options if any */
while (*my_argv[1] == '-') {
p = (char *) &*my_argv[1];
p++; /* point to the option chars */
do {
switch (*p) {
case ' ':
case '\0': /* ignore nulls and spaces */
break;
case 'p': case 'P': /* turn on proportional mode */
Write(printer, "\x1b[2p", 3L);
break;
case 'c': case 'C': /* turn on compressed mode */
Write(printer, "\x1b[4w", 4L);
break;
case 'u': case 'U': /* turn on uncompressed mode */
Write(printer, "\x1b[3w", 4L);
break;
case 'l': case 'L': /* turn on letter quality mode */
Write(printer, "\x1b[2\"z", 5L);
break;
case 'd': case 'D': /* turn on draft mode */
Write(printer, "\x1b[1\"z", 5L);
break;
case ':': /* print control string first */
strcpy(theprefix, ++p);
prefix++;
goto next; /* consume rest of option */
case '^': /* print control chars as ^X */
control++;
break;
case 't': case 'T': /* set tab stops */
p++;
if (isdigit(*p))
tab_stops = *p - '0';
else {
tab_stops = 8;
p--;
}
break;
case '#': /* set lines per page */
p++;
lines_per_page = 0;
while(isdigit(*p)) {
lines_per_page *= 10;
lines_per_page += (*p++ - '0');
}
p--;
break;
case '|': /* set chars per line */
p++;
chars_per_line = 0;
while(isdigit(*p)) {
chars_per_line *= 10;
chars_per_line += (*p++ - '0');
}
p--;
break;
case 'n': case 'N': /* print line numbers */
numbers++;
break;
case 'h': /* print a header */
headers++;
break;
default:
/* ignore invalid stuff for now */;
}
p++;
} while (*p);
next:
my_argc--;
my_argv++;
}
/* put out the control prefix if any */
if (prefix) {
p = theprefix;
while(*p) {
if (*p == '^') {
p++;
c = *p - '@';
Write(printer, &c, 1L);
} else
Write(printer, *p, 1L);
p++;
}
/* reset the prefix flag */
prefix = 0;
}
/* now print the file */
print_one_file(my_argv[1]);
my_argv++;
}
Close(printer);
printer = 0;
}
static char buf[1024]; /* Note! if called from WB we have */
static char outbuf[1024+100]; /* very limited stack space */
/* do the actual print for a file */
print_one_file(name)
char *name;
{
long in;
long bytes, Read();
register long outbytes;
register char *p;
int line;
int page;
int num_lines;
int new_line;
int chars;
char line_buf[10];
char ctl[4];
int i;
in = Open(name, MODE_OLDFILE);
if (!in) {
sprintf(buf, "unable to open: '%s'\f", name);
Write(printer, buf, (long) strlen(buf));
return;
}
line = 1;
page = 1;
/* print a file header if desired */
if (headers) {
sprintf(buf, "File: %s Page %d\n\n", name, page);
Write(printer, buf, (long) strlen(buf));
num_lines = 3;
} else
num_lines = 1;
if (numbers || control || lines_per_page || chars_per_line) {
outbytes = 0;
if (numbers) {
sprintf(outbuf, "%4d ", line);
outbytes = strlen(outbuf);
chars = outbytes;
}
/* now read the file a block at a time */
while(bytes = Read(in, buf, 1024L)) {
p = buf;
if (bytes < 0) {
sprintf(buf, "Error reading file: %s\n", name);
Write(printer, buf, (long) sizeof(buf));
return;
}
/* now write out this block */
while(bytes) {
/* check for control chars, if requested */
if (control) {
if ((*p < ' ')&&(*p != '\n')&&(*p != '\t')){
/* print all other control chars in ^A format */
outbuf[outbytes++] = '^';
*p += '@';
chars++;
}
}
/* check for a new line */
if ((*p == '\n')||(*p == '\f')) {
/* newline, need a page break? */
if (((*p == '\f') && (!control)) ||
(lines_per_page && (num_lines >= lines_per_page))) {
/* is this a user formfeed */
if (*p == '\f') {
sprintf(buf, "<form feed>\f");
strcpy(&outbuf[outbytes], buf);
outbytes += strlen(buf);
line--;
} else
outbuf[outbytes++] = '\f';
/* print a file header if desired */
page++;
if (headers) {
sprintf(buf, "File: %s Page %d\n\n",
name, page);
strcpy(&outbuf[outbytes], buf);
outbytes += strlen(buf);
num_lines = 2;
} else
num_lines = 0;
}
line++;
num_lines++;
new_line = 1;
} else
new_line = 0;
/* now put the character and account for it */
chars++;
bytes--;
switch (*p) {
case '\t':
if (tab_stops) {
if ((chars % tab_stops) == 0) {
for(i=0; i < tab_stops; i++) {
outbuf[outbytes++] = ' ';
chars++;
}
} else
while(chars % tab_stops) {
outbuf[outbytes++] = ' ';
chars++;
}
p++;
} else {
while(chars % 8) chars++;
outbuf[outbytes++] = *p++;
}
break;
case '\f': /* formfeeds are accounted for eariler */
p++;
break;
case 8:
chars--;
outbuf[outbytes++] = *p++;
break;
default:
outbuf[outbytes++] = *p++;
}
/* check for line overflow, if requested */
if (chars_per_line && (chars >= chars_per_line)) {
outbuf[outbytes++] = '\n';
num_lines++;
if (numbers) {
strcpy(&outbuf[outbytes], " ");
outbytes += 5;
chars = 5;
} else
chars = 0;
}
/* now put out the line number if needed */
if (new_line && numbers) {
sprintf(&outbuf[outbytes], "%4d ", line);
outbytes += 5;
chars = 5;
}
/* dump the buffer if near full */
if (outbytes >= 1000L) {
Write(printer, outbuf, outbytes);
outbytes = 0;
}
} /* while chars in this block */
} /* while not EOF */
/* flush last line */
if (outbytes)
Write(printer, outbuf, outbytes);
} else {
/* we can just pump out the data untouched */
while(bytes = Read(in, buf, 1024L))
if (bytes > 0)
Write(printer, buf, bytes);
else {
sprintf(buf, "Error reading file");
Write(printer, buf, (long) sizeof(buf));
}
}
Write(printer, "\f", 1L);
Close(in);
in = 0;
}
set_up_print(name)
char *name;
{
long save;
extern long tty;
extern char **av;
extern int called_from_WB;
extern long current_dir;
char option_string[80];
char numbuf[16];
char c;
int i;
char buf[100];
long result, Execute();
int fake_argc;
char *fake_argv[4];
/*
* print the current file
*/
save = tty;
/* first make sure we can get the printer */
printer = Open("PRT:", MODE_NEWFILE);
if (!printer) {
error("can't access the printer at this time");
} else {
/* printer is avail so... */
tty = Open("RAW:100/50/470/100/Less's print server", MODE_NEWFILE);
if (!tty) {
tty = save;
Close(printer);
printer = 0;
error("Can't open window!");
return;
}
ttputs("Print File: ");
ttputs(name);
ttputs("\nEnter the first letter of each option, if any\n");
ttputs("For example 'nh#60|80t8^l', the options are...\n");
so_enter();
ttputs("numberedlines headers ^ctrl proportional \n");
ttputs("letterquality draft wide uncompressed \n");
ttputs("#<num> of rows, |<num> of columns, t<num> tabstop\n");
so_exit();
ttputs("\nOptions or 'q' to quit? ");
/* get a responce */
i = 0;
while (c = ttgetc()) {
if (c == 8) { /* backspace ? */
if (i > 0) {
i--;
ttputc(c);
}
} else {
if ((c < ' ') || (i > 32)) break;
option_string[i++] = c;
ttputc(c);
}
}
option_string[i] = 0;
if(toupper(option_string[0]) != 'Q') {
if (called_from_WB) {
/* I haven't figured out how to queue from WB */
#ifndef WB_QUEUED
if (option_string[0]) {
sprintf(buf, "-%s", option_string);
fake_argc = 3;
fake_argv[1] = buf;
fake_argv[2] = name;
} else {
fake_argc = 2;
fake_argv[1] = name;
}
fake_argv[fake_argc] = NULL;
ttputs("\nPrinting...\n");
start_print(fake_argc, fake_argv);
ttputs("Complete!\n");
#else
/* this should work but I can't figure out why not */
sprintf(buf, "RUN %s -p %ld ", prog_name, current_dir);
if (option_string[0]) {
strcat(buf, "-");
strcat(buf, option_string);
strcat(buf, " ");
}
strcat(buf, name);
/* give up the printer */
Close(printer);
printer = 0;
/* and execute the job */
std_out = Open("NIL:", MODE_OLDFILE);
result = Execute(buf, 0L, std_out);
if (result) {
ttputs("\nJob queued\n");
} else {
sprintf(buf, "\nError on Execute: %ld", result);
ttputs(buf);
}
#endif
} else {
/* from CLI, queue it to a copy of myself */
sprintf(buf, "RUN %s -p ", prog_name);
if (option_string[0]) {
strcat(buf, "-");
strcat(buf, option_string);
strcat(buf, " ");
}
strcat(buf, name);
/* give up the printer */
Close(printer);
printer = 0;
/* and execute the job */
result = Execute(buf, 0L, 0L);
if (result) {
ttputs("\nJob queued\n");
} else {
sprintf(buf, "\nError on Execute: %ld", result);
ttputs(buf);
}
}
} else {
Close(printer);
printer = 0;
ttputs("\nPrint request canceled by user!\n");
}
Delay(100L);
ttclose();
tty = save;
}
}